package com.aiti.lulian.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.base.service.iml.BaseSerivceImpl;
import com.aiti.base.core.constant.MessageCodeConstant;
import com.aiti.base.core.utils.message.Message;
import com.aiti.lulian.dto.CustomerManagementDto;
import com.aiti.lulian.dto.crm.CrmFollowRecordDto;
import com.aiti.lulian.entity.*;
import com.aiti.lulian.entity.crm.CrmFollowRecord;
import com.aiti.lulian.feign.CloudShowManagerSubService;
import com.aiti.lulian.mapper.CustomerFollowUpRecordMapper;
import com.aiti.lulian.mapper.ShangJiFollowUpRecordMapper;
import com.aiti.lulian.mapper.card.crm.CrmFollowRecordMapper;
import com.aiti.lulian.service.CardBusinessContractService;
import com.aiti.lulian.service.ICommunicateInfoService;
import com.aiti.lulian.service.ICrmFollowRecordService;
import com.aiti.lulian.service.ICustomerManagementService;
import com.aiti.lulian.utils.DateFilterUtil;
import com.aiti.lulian.vo.crm.CrmFollowRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class CrmFollowRecordServiceImpl extends BaseSerivceImpl<CrmFollowRecordMapper, CrmFollowRecord> implements ICrmFollowRecordService {

    @Autowired
    private CrmFollowRecordMapper crmFollowRecordMapper;

    @Autowired
    private CustomerFollowUpRecordMapper customerFollowUpRecordMapper;

    @Autowired
    private ShangJiFollowUpRecordMapper shangJiFollowUpRecordMapper;

    @Autowired
    private ICustomerManagementService customerManagementService;

    @Autowired
    private ICommunicateInfoService communicateInfoService;

    @Autowired
    private CloudShowManagerSubService cloudShowManagerSubService;

    @Autowired
    private CardBusinessContractService cardBusinessContractService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Message writeFollowRecord(CrmFollowRecordDto dto) {
        CrmFollowRecord crmFollowRecord = new CrmFollowRecord();
        // 如果没有实际跟进时间，则将实际跟进时间设置为当前时间。因为表结构设计需要设置值
        if(dto.getPracticalFollowTime() == null) {
            dto.setPracticalFollowTime(new Date());
        }
        BeanUtils.copyProperties(dto, crmFollowRecord);
        crmFollowRecordMapper.insert(crmFollowRecord);

        Date nextFollowTime = dto.getNextFollowTime();
        String creator = dto.getCreator();
        if (StrUtil.equals(dto.getObjectType(), "1")) {
            //若当前跟进对象为客户类型，同时往原客户跟进记录表中存储一份数据
            String customerId = dto.getObjectId();
            CustomerFollowUpRecord customerFollowUpRecord = CustomerFollowUpRecord.builder()
                    .followUpType(dto.getFollowType())
                    .followUpTime(dto.getPracticalFollowTime())
                    .content(dto.getContent())
                    .customerId(customerId)
                    .followUpState(dto.getStatus())
                    .linkMan(dto.getLinkman())
                    .nextFollowUpTime(nextFollowTime)
                    .recordType("1")
                    .enterpriseId(dto.getEnterpriseId())
                    .baseCreateBy(creator)
                    .baseCreateTime(new Date())
                    .baseUpdateTime(new Date())
                    .cfrId(crmFollowRecord.getBaseId())
                    .followUpState(dto.getStatus())
                    .followUpObj(dto.getFollowUpObj())
                    .build();

            customerFollowUpRecord.setFollowUpTime(dto.getPracticalFollowTime());
            customerFollowUpRecordMapper.insert(customerFollowUpRecord);
            //更新该客户的下次跟进时间字段
            customerManagementService.update(new LambdaUpdateWrapper<CustomerManagement>()
                    .eq(CustomerManagement::getBaseId, customerId)
                    .set(CustomerManagement::getNextFollowTime, nextFollowTime)
                    .set(CustomerManagement::getUpdateBy, creator)
                    .set(CustomerManagement::getFollowStatus, dto.getStatus())
                    .set(CustomerManagement::getBaseUpdateTime, new Date()));
            if (StrUtil.equals(dto.getIsPublic(), "1")) {
                //同步划入公海
                CustomerManagementDto customerManagementDto = new CustomerManagementDto();
                List<String> customerIds = Arrays.asList(customerId);
                customerManagementDto.setCustomerIds(customerIds);
                customerManagementDto.setIsPublic("1");
                customerManagementDto.setUserId(creator);
                customerManagementService.forwardCustomer(customerManagementDto);
            }
        } else if (StrUtil.equals(dto.getObjectType(), "2")) {
            //若当前跟进对象为商机类型，同时往原商机跟进记录表中存储一份数据
            String shangJiId = dto.getObjectId();
            ShangjiFollowUpRecord shangjiFollowUpRecord = ShangjiFollowUpRecord.builder()
                    .followUpType(dto.getFollowType())
                    .followUpTime(dto.getPracticalFollowTime())
                    .content(dto.getContent())
                    .customerId(shangJiId)
                    .followUpStage(dto.getStatus())
                    .linkMan(dto.getLinkman())
                    .nextFollowUpTime(dto.getNextFollowTime())
                    .recordType("2")
                    .enterpriseId(dto.getEnterpriseId())
                    .baseCreateBy(creator)
                    .baseCreateTime(new Date())
                    .baseUpdateTime(new Date())
                    .cfrId(crmFollowRecord.getBaseId())
                    .followUpObj(dto.getFollowUpObj())
                    .build();
            shangJiFollowUpRecordMapper.insert(shangjiFollowUpRecord);
            //更新该商机的下次跟进时间字段
            communicateInfoService.update(new LambdaUpdateWrapper<CommunicateInfo>()
                    .eq(CommunicateInfo::getBaseId, shangJiId)
                    .set(CommunicateInfo::getNextFollowUpTime, nextFollowTime)
                    .set(CommunicateInfo::getUpdateBy, creator)
                    .set(CommunicateInfo::getBaseUpdateTime, new Date()));
        } else {
            //若当前跟进对象为合同类型，更新该合同的下次跟进时间字段
            String contractId = dto.getObjectId();
            cardBusinessContractService.update(new LambdaUpdateWrapper<CardBusinessContract>()
                    .eq(CardBusinessContract::getBaseId, contractId)
                    .set(CardBusinessContract::getNextFollowUpTime, nextFollowTime)
                    .set(CardBusinessContract::getBaseUpdateBy, creator)
                    .set(CardBusinessContract::getBaseUpdateTime, new Date()));
        }

        return Message.success("保存成功");
    }

    @Override
    public List<CrmFollowRecordVo> getFollowRecordList(CrmFollowRecordDto dto, Page<CrmFollowRecord> page) {
        String baseCreateTimeDateType = dto.getBaseCreateTimeDateType();
        if (StrUtil.isNotBlank(baseCreateTimeDateType)) {
            Map<String, DateTime> beginAndEnd = DateFilterUtil.getBeginAndEnd(baseCreateTimeDateType);
            dto.setBeginBaseCreateTime(beginAndEnd.get("begin"));
            dto.setEndBaseCreateTime(beginAndEnd.get("end"));
        }
        String nextFollowTimeDateType = dto.getNextFollowTimeDateType();
        if (StrUtil.isNotBlank(nextFollowTimeDateType)) {
            Map<String, DateTime> beginAndEnd = DateFilterUtil.getBeginAndEnd(nextFollowTimeDateType);
            dto.setBeginNextFollowTime(beginAndEnd.get("begin"));
            dto.setEndNextFollowTime(beginAndEnd.get("end"));
        }

        Date baseCreateTimeBegin = dto.getBaseCreateTimeBegin();
        Date baseCreateTimeEnd = dto.getBaseCreateTimeEnd();
        if (baseCreateTimeBegin != null & baseCreateTimeEnd != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(baseCreateTimeEnd);
            calendar.add(Calendar.DATE, 1);
            dto.setBaseCreateTimeEnd(calendar.getTime());
        }
        Date nextFollowTimeBegin = dto.getNextFollowTimeBegin();
        Date nextFollowTimeEnd = dto.getNextFollowTimeEnd();
        if (nextFollowTimeBegin != null & nextFollowTimeEnd != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nextFollowTimeEnd);
            calendar.add(Calendar.DATE, 1);
            dto.setNextFollowTimeEnd(calendar.getTime());
        }

        //获取当前用户的权限
        String scope = null;
        String userId = dto.getUserId();
        Message userAccessScopeMessage = cloudShowManagerSubService.queryUserAccessScope(userId);
        if (userAccessScopeMessage == null) {
            throw new RuntimeException("获取用户访问权限失败");
        } else if (! userAccessScopeMessage.getCode().equals(MessageCodeConstant.MSG_SUCCESS_CODE)) {
            throw new RuntimeException("查询用户访问权限失败");
        } else {
            scope = (String) userAccessScopeMessage.getObj();
            dto.setScope(scope);
            if (! StrUtil.equals(scope, "4")) {
                //判断该用户是否为部门负责人
                Message userInfoMessage = cloudShowManagerSubService.getUserInfo(userId);
                if (userInfoMessage == null) {
                    throw new RuntimeException("获取用户信息失败");
                } else if (! userInfoMessage.getCode().equals(MessageCodeConstant.MSG_SUCCESS_CODE)) {
                    throw new RuntimeException("查询用户信息失败");
                } else {
                    Object obj = userInfoMessage.getObj();
                    if (obj == null) {
                        throw new RuntimeException("查询用户为空");
                    }
                    ObjectMapper mapper = new ObjectMapper();
                    Map userInfoMap = mapper.convertValue(obj, Map.class);
                    String deptPermission = (String) userInfoMap.get("deptPermission");
                    String deptId = (String) userInfoMap.get("deptId");

                    //若为部门负责人，则获取其部门下所有成员ID集
                    if (StrUtil.equals(deptPermission, "1")) {
                        Message getUserIdsMessage = cloudShowManagerSubService.getUserIdsByDeptId(deptId);
                        if (getUserIdsMessage == null) {
                            throw new RuntimeException("获取部门成员失败");
                        } else if (! getUserIdsMessage.getCode().equals(MessageCodeConstant.MSG_SUCCESS_CODE)) {
                            throw new RuntimeException("查询部门成员失败");
                        } else {
                            List<String> userIds = (List<String>) getUserIdsMessage.getObj();
                            if (userIds == null) {
                                throw new RuntimeException("查询部门成员为空");
                            }
                            dto.setUserIds(userIds);
                        }
                    }
                }
            }
        }

        return crmFollowRecordMapper.selectFollowRecordList(dto, page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Message deleteFollowRecord(CrmFollowRecordDto dto) {
        List<CrmFollowRecord> followRecords = dto.getFollowRecords();
        for (CrmFollowRecord followRecord : followRecords) {
            String baseId = followRecord.getBaseId();
            this.removeById(baseId);
            String objectType = followRecord.getObjectType();
            if (StrUtil.equals(objectType, "客户")) {
                //客户 -> 需要删除同步到原客户跟进记录表中的数据
                customerFollowUpRecordMapper.delete(new LambdaQueryWrapper<CustomerFollowUpRecord>().eq(CustomerFollowUpRecord::getCfrId, baseId));
            } else if (StrUtil.equals(objectType, "商机")) {
                //商机 -> 需要删除同步到原商机跟进记录表中的数据
                shangJiFollowUpRecordMapper.delete(new LambdaQueryWrapper<ShangjiFollowUpRecord>().eq(ShangjiFollowUpRecord::getCfrId, baseId));
            }
        }
        return Message.success("删除成功");
    }

    @Override
    public List<CrmFollowRecord> getListByCustomerId(String customerId) {
        return baseMapper.selectListByCustomerId(customerId);
    }
}